package tt.dz.tcp.rpc.ms;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.avro.Protocol;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.generic.GenericRequestor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import tt.dz.entity.exception.BizException;
import tt.dz.tcp.rpc.ms.client.entity.*;
import tt.dz.tcp.rpc.ms.client.entity.MasterModifyOperInfoVO.MasterModifyOperInfoParamVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterModifyOperInfoVO.MasterModifyOperInfoRetVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterModifyOperRoleVO.MasterModifyOperRoleParamVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterModifyOperRoleVO.MasterModifyOperRoleRetVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryCardsVO.MasterQueryCardStateParamVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryCardsVO.MasterQueryCardStateRetVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryCardsVO.MasterQueryCardsParamVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryCardsVO.MasterQueryCardsRetVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryIdentityCardVO.MasterQueryIdentityCardParamVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryIdentityCardVO.MasterQueryIdentityCardRetVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryOfflineCardVO.MasterQueryOfflineCardParamVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryOfflineCardVO.MasterQueryOfflineCardRetVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryUserDetailByCardVO.MasterQueryUserDetailByCardParamVO;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryUserDetailByCardVO.MasterQueryUserDetailByCardRetVO;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;

/**
 * 用于和主服务通信
 * 
 * 后续将会优化。
 * @author Administrator
 *
 */
@Component
public class SystemMasterServerRpcClient 
{
	private Log log = LogFactory.getLog(SystemMasterServerRpcClient.class);

	@Value(value="${masterServerIp}")
	private String masterServerIp;
	
	@Value(value="${masterServerPort}")
	private int port;
	@Value(value="${masterFileName}")
	private String protocolFile ;
	@Value("${masterOmsCode}")
	private String masterOmsCode;
	
	private Protocol protocol;

	public SystemMasterServerRpcClient() {}

    @PostConstruct
	public void init(){
    	try 
    	{
			String filePath = this.getClass().getResource(protocolFile).getPath();
			try {
				filePath = URLDecoder.decode(filePath, "UTF-8");
			} catch (UnsupportedEncodingException e1) {
				log.error("初始化主服务器客户端错误", e1);
			}
			protocol = Protocol.parse(new File(filePath));
		} catch (IOException e) 
    	{
			log.error("初始化主服务器客户端错误", e);
		}
    }
    
    /**
     * 管理员系统登录接口
     * @param obj
     * @return
     */
	public MasterLoginResult systemLoginInteface(MasterLoginParam obj) //throws BizException
	{
		NettyTransceiver transceiver = null;
		obj.setSysCode(masterOmsCode);
		try
		{
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("loginForOper").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
			Object result = requestor.request("loginForOper", requestData);
			log.info(result);
			if (result != null)
			{
				MasterLoginResult retVO = JSON.parseObject(result.toString(), MasterLoginResult.class);
				return retVO;
			}
		}
		catch (Exception e)
		{
			log.error("主服务器登录报错", e);
//			throw new BizException(e);
		}
		finally
		{
			if (transceiver != null)
			{
				transceiver.close();
			}
		}
		return null;
	}

	/**
     * 企业用户登录接口（登录（外部用户））
     */
    public MasterLoginResult systemOtherLoginInteface(MasterOtherLoginParam obj){
    	NettyTransceiver transceiver = null;
    	obj.setSysCode(masterOmsCode);
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("login").getRequest());  
			requestData.put("loginReq", JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("login", requestData);
	        if (result != null)
	        {
		        MasterLoginResult retVO = JSON.parseObject(result.toString(), MasterLoginResult.class);
		        return retVO;
		    }
		} 
		catch (Exception e) 
		{
			log.error("主服务器登录报错", e);
		} 
		finally 
		{
			if(transceiver != null)
			{
				transceiver.close();
			}
		}
		return null;
    }
    
    
    public MasterQueryUserByDateResult systemUserQueryInteface(MasterQueryUserByDateParam obj){
    	NettyTransceiver transceiver = null;
    	obj.setSysCode(masterOmsCode);
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryOperListBySys").getRequest());  
			requestData.put("req", JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("queryOperListBySys", requestData);
	        MasterQueryUserByDateResult retVO = JSON.parseObject(result.toString(), MasterQueryUserByDateResult.class);
	        if (retVO.getIsSuccess() == 1)
	        {
	        	retVO.setUsers(JSON.parseArray(retVO.getResult(),MasterUser.class));
	        }
	        return retVO;
		} 
		catch (Exception e) 
		{
			log.error("主服务同步用户", e);
			e.printStackTrace();
		} 
		finally 
		{
			if(transceiver != null)
			{
				transceiver.close();
			}
		}
		return null;
    }
    
    public MasterAddUserReturn addSysUser(MasterAddUserParam obj){
    	NettyTransceiver transceiver = null;
    	obj.setSysCode(masterOmsCode);
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("addSysUser").getRequest());
			log.info(obj);
			requestData.put("req", JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
	        Object result = requestor.request("addSysUser", requestData);
			log.info(result);
	        if (result != null){
				MasterAddUserReturn retVO = JSON.parseObject(result.toString(), MasterAddUserReturn.class);
	        return retVO;
	        }
		} 
		catch (Exception e) 
		{
			log.error("添加用户", e);
		} 
		finally 
		{
			if(transceiver != null)
				transceiver.close();
		}
		return null;
    }
    
    public MasterModifyOperRoleRetVO addSysRole(MasterAddRoleParam obj) throws IOException
	{
    	NettyTransceiver transceiver = null;
    	obj.setSysCode(masterOmsCode);
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("addSysRole").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
	        Object result = requestor.request("addSysRole", requestData);
			log.info(result);
			MasterModifyOperRoleRetVO retVO = JSON.parseObject(result.toString(), MasterModifyOperRoleRetVO.class);
	        return retVO;
		} 
		catch (Exception e) 
		{
			log.error("添加角色", e);
			throw e;
		}
		finally 
		{
			if(transceiver != null)
			{
				transceiver.close();
			}
		}
    }
    
    public MasterMerchantResult systemQueryMerchantInteface(MasterMerchantParam obj) throws BizException
	{
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryMerchant").getRequest());  
			requestData.put("req", JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
	        Object result = requestor.request("queryMerchant", requestData);
			log.info(result);
			if(result != null)
			{
				MasterMerchantResult retVO = JSON.parseObject(result.toString(), MasterMerchantResult.class);
				return retVO;
			}
		} 
		catch (Exception e) 
		{
			log.error("查询运营商", e);
			throw new BizException(e);
		} 
		finally 
		{
			if(transceiver != null)
			{
				transceiver.close();
			}
		}
		return null;
    }

	public MasterBaseReturn systemUserModifyPwdInteface(MasterModifyPwdParam obj) throws BizException
	{
		NettyTransceiver transceiver = null;
		try
		{
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("modifyOperPassword").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
			Object result = requestor.request("modifyOperPassword", requestData);
			log.info(result);
			if (result != null)
			{
				MasterBaseReturn retVO = JSON.parseObject(result.toString(), MasterBaseReturn.class);
				return retVO;
			}
			return null;
		}
		catch (Exception e)
		{
			log.error("修改密码错误", e);
			throw new BizException(e);
		}
		finally
		{
			if (transceiver != null)
				transceiver.close();

		}
	}

	/**
	 * 修改操作员角色
	 */
	public MasterModifyOperRoleRetVO modifyOperRole(MasterModifyOperRoleParamVO paramVO)
	{
		paramVO.setSysCode(masterOmsCode);
		NettyTransceiver transceiver = null;
		try
		{
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("modifyOperRole").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(paramVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
			Object result = requestor.request("modifyOperRole", requestData);
			log.info(result);
			if (result != null)
			{
				MasterModifyOperRoleRetVO retVO = JSON.parseObject(result.toString(), MasterModifyOperRoleRetVO.class);
				return retVO;
			}
		}
		catch (Exception e)
		{
			log.error("修改操作员角色出错", e);
		}
		finally
		{
			if (transceiver != null)
			{
				transceiver.close();
			}
		}
		return null;
	}

	/**
     * 修改操作员信息
     */
	public MasterModifyOperInfoRetVO modifyOperInfo(MasterModifyOperInfoParamVO paramVO)
	{
		paramVO.setSysCode(masterOmsCode);
		NettyTransceiver transceiver = null;
		try
		{
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("modifyOperInfo").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(paramVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
			Object result = requestor.request("modifyOperInfo", requestData);
			log.info(result);
			if (result != null)
			{
				MasterModifyOperInfoRetVO retVO = JSON.parseObject(result.toString(), MasterModifyOperInfoRetVO.class);
				return retVO;
			}
		}
		catch (Exception e)
		{
			log.error("修改操作员信息", e);
		}
		finally
		{
			if (transceiver != null)
			{
				transceiver.close();
			}
		}
		return null;
	}

	/**
     * 查询现金卡状态
     */
    public MasterQueryOfflineCardRetVO queryOfflineCard(MasterQueryOfflineCardParamVO paramVO){
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryOfflineCard").getRequest());  
			requestData.put("req", JSON.toJSONStringWithDateFormat(paramVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("queryOfflineCard", requestData);
	        if (result != null) {
				log.info(result);
	        	MasterQueryOfflineCardRetVO retVO = JSON.parseObject(result.toString(), MasterQueryOfflineCardRetVO.class);
	        	return retVO;
	        }
		} catch (Exception e) {
			log.error("查询现金卡状态出错", e);
		} finally {
			if (transceiver != null) {
				transceiver.close();
			}
		}
		return null;
    }
    
    /**
     * 查询身份识别卡状态
     */
    public MasterQueryIdentityCardRetVO queryIdentityCardByNo(MasterQueryIdentityCardParamVO paramVO){
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryIdentityCardByNo").getRequest());  
			requestData.put("req", JSON.toJSONStringWithDateFormat(paramVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("queryIdentityCardByNo", requestData);
	        if (result != null) {
	        	MasterQueryIdentityCardRetVO retVO = JSON.parseObject(result.toString(), MasterQueryIdentityCardRetVO.class);
	        	return retVO;
	        }
		} catch (Exception e) {
			log.error("查询身份识别卡状态出错", e);
		} finally {
			if (transceiver != null) {
				transceiver.close();
			}
		}
		return null;
    }
    

    
    /**
     * 通过卡号查询客户信息
     */
    public MasterQueryUserDetailByCardRetVO queryUserDetailByCard(MasterQueryUserDetailByCardParamVO paramVO){
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryUserDetailByCard").getRequest());  
			requestData.put("req", JSON.toJSONStringWithDateFormat(paramVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("queryUserDetailByCard", requestData);
	        if (result != null) {
	        	MasterQueryUserDetailByCardRetVO retVO = JSON.parseObject(result.toString(), MasterQueryUserDetailByCardRetVO.class);
	        	return retVO;
	        }
		} catch (Exception e) {
			log.error("通过卡号查询客户信息出错", e);
		} finally {
			if (transceiver != null) {
				transceiver.close();
			}
		}
		return null;
    }
    
    /**
     * 查询关联卡
     */
    public MasterQueryCardsRetVO queryCards(MasterQueryCardsParamVO paramVO){
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryCards").getRequest());  
			requestData.put("req", JSON.toJSONStringWithDateFormat(paramVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("queryCards", requestData);
	        if (result != null) {
	        	MasterQueryCardsRetVO retVO = JSON.parseObject(result.toString(), MasterQueryCardsRetVO.class);
	        	return retVO;
	        }
		} catch (Exception e) {
			log.error("查询关联卡信息出错", e);
		} finally {
			if (transceiver != null) {
				transceiver.close();
			}
		}
		return null;
    }

	/**
	 * 查询卡状态
	 */
	public MasterQueryCardStateRetVO queryCardState(MasterQueryCardStateParamVO paramVO){
		NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryCards").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(paramVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			Object result = requestor.request("queryCardState", requestData);
			System.out.println(result);
			if (result != null) {
				MasterQueryCardStateRetVO retVO = JSON.parseObject(result.toString(), MasterQueryCardStateRetVO.class);
				System.out.println(retVO);
				return retVO;
			}
		} catch (Exception e) {
			log.error("查询卡状态出错", e);
		} finally {
			if (transceiver != null) {
				transceiver.close();
			}
		}
		return null;
	}

	public MasterQueryUserReturn queryUser(MasterQueryUserParam param) throws IOException
	{
		NettyTransceiver transceiver = null;
		try
		{
			transceiver = new NettyTransceiver(new InetSocketAddress(masterServerIp, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("queryUser").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(param, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
			Object result = requestor.request("queryUser", requestData);
//			log.info(result);
			if(result != null)
			{
				MasterQueryUserReturn retVO = JSON.parseObject(result.toString(), MasterQueryUserReturn.class);
				return retVO;
			}
		}
		catch (IOException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
		finally
		{
			if (transceiver != null)
			{
				transceiver.close();
			}
		}
		return null;
	}
}
